/* 
 * Copyright 2010 HIT-CIR (HIT Center for Information Retrieval). 
 * 
 * author: chuter
 * mail:   lliu@ir.hit.edu.cn
 */
package nlpeap.knowledge;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.HashMap;
import java.util.HashSet;

import nlpeap.feature.basictypes.GenderType;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.sun.corba.se.impl.encoding.OSFCodeSetRegistry.Entry;

import nlpeap.config.ConfigProperties;

/**
 * 
 * @author chuter
 * 
 */
public class NameDataBase {
	public static Log _log = LogFactory.getLog(NameDataBase.class.getName());
	private final ConfigProperties conf = ConfigProperties.getInstance();
	private final HashSet<String> femaledic;
	private final HashSet<String> maledic;
	private final HashMap<String, String> aliasdic;
	private final HashMap<String, Double> lastwordfreqdic;

	private static NameDataBase _instance;

	/** Creates a new instance of NameDataBase */
	@SuppressWarnings("unchecked")
	private NameDataBase() 
	{
		maledic = (HashSet<String>) getNameDB(conf.getMaleDicPath());
		femaledic = (HashSet<String>) getNameDB(conf.getFemaleDicPath());
		aliasdic = (HashMap<String, String>) getNameDB(conf.getAliasDicPath());
		lastwordfreqdic = (HashMap<String, Double>) getNameDB(conf
				.getGenderDicPath());
	}

	public static NameDataBase getInstance() 
	{
		if (_instance == null)
			_instance = new NameDataBase();

		return _instance;
	}

	/** load the dbs: female_dic, male_dic, alias_dic */
	private Object getNameDB(String dic_path) 
	{
		FileInputStream fis;
		Object load_obj = null;
		try {
			fis = new FileInputStream(new File(dic_path));
			ObjectInputStream in = new ObjectInputStream(fis);
			load_obj = in.readObject();
		} catch (FileNotFoundException e) {
			_log.debug("can't find the dictionary: " + dic_path);
		} catch (IOException e) {
			_log.debug("dictionary load error: " + dic_path);
		} catch (ClassNotFoundException e) {
			_log.debug(e.toString() + ": " + dic_path);
		}

		return load_obj;
	}

	/**
	 * return the gender associated with the given name or <i>null</i> if it's
	 * not in the map.
	 */
	public GenderType lookup(final String name) 
	{
		if (maledic.contains(name) && femaledic.contains(name))
			return GenderType.BOTH;
		else if (femaledic.contains(name))
			return GenderType.FEMALE;
		else if (maledic.contains(name))
			return GenderType.MALE;
		else
			return null;
	}

	/**
	 * get the frequency of the name is for Male, which with the <i>word</i> as
	 * it's last word
	 */
	public double lastwordFreForMaleName(String word) 
	{
		return lastwordfreqdic.containsKey(word) ? lastwordfreqdic.get(word)
				: 0;
	}

	/**
	 * return the real name associated with the given name(alias name,) or
	 * <i>alias_name</i> if it's not in the map.
	 */
	public String lookupRealName(final String alias_name) 
	{
		if (aliasdic.containsKey(alias_name))
			return aliasdic.get(alias_name);
		return alias_name;
	}

	public HashSet<String> getMaleDic() 
	{ return this.maledic; }

	public HashSet<String> getFeMaleDic() 
	{ return this.femaledic; }

	public HashMap<String, String> getFeAliasDic() 
	{ return this.aliasdic; }

	// for markable interface
	// public GenderType lookup(final Markable markable) {
	// return null;
	// }
}
